package com.atguigu.gmall.es;

import com.alibaba.fastjson.JSON;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.index.reindex.UpdateByQueryRequest;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class EsClientDemo {
    public static void main(String[] args) throws IOException {
        //System.out.println(esClient);
        //put();
        //post();
        //bulk();
        //updateByID();
        //updateByQUery();
        //deleteById();
        //deleteByQuery();
        getById();

        close();
    }

    /**
     * search
     * 查询doubanscore>=5.0,关键词搜索red sea
     * 关键词高亮显示
     * 显示第一页，每页两条
     * 按doubanscore降序
     *
     */
    public static void search() throws IOException {
        String indexName = "movie_index";

        SearchRequest searchRequest = new SearchRequest(indexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //query
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //must ->match
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name","red sea");
        boolQueryBuilder.must(matchQueryBuilder);
        //filter ->range
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("doubanScore").gte(5.0);
        boolQueryBuilder.filter(rangeQueryBuilder);
        searchSourceBuilder.query(boolQueryBuilder);
        //分页
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(1);
        //排序
        searchSourceBuilder.sort("doubanScore", SortOrder.ASC);
        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
        searchSourceBuilder.highlighter(highlightBuilder);

        searchRequest.source(searchSourceBuilder);
        SearchResponse searchRespose = esClient.search(searchRequest, RequestOptions.DEFAULT);

        //查询结果
        SearchHit[] searchHits = searchRespose.getHits().getHits();
        for (SearchHit searchHit : searchHits) {
            //取查询结果
            String source = searchHit.getSourceAsString();
            //获取高亮
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            HighlightField name = highlightFields.get("name");
            Text[] fragments = name.getFragments();
            String highLight = fragments[0].toString();
            System.out.println(source);
            System.out.println(highLight);
        }

    }


    /**
     * 查询，基于id
     */
    public static void getById() throws IOException {
        String indexName = "movie_2022";
        String docId = "1001";
        GetRequest getRequest = new GetRequest(indexName,docId);
        GetResponse getRespose = esClient.get(getRequest, RequestOptions.DEFAULT);
        String sourceAsString = getRespose.getSourceAsString();
        Map<String, Object> stringObjectMap = getRespose.getSource();
        System.out.println(stringObjectMap);
        System.out.println(sourceAsString);
    }


    /**
     * 删除数据，基于id删除
     *
     * 删除数据，基于查询删除
     */
    public static void deleteById() throws IOException {
        String indexName = "movie_index";
        String docId = "1001";
        DeleteRequest deleteRequest = new DeleteRequest(indexName,docId);
        esClient.delete(deleteRequest,RequestOptions.DEFAULT);
    }
    public static void deleteByQuery() throws IOException {
        String indexName = "movie_index";
        DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(indexName);
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("movieName.keyword", "湄公河行动");
        deleteByQueryRequest.setQuery(termQueryBuilder);

        esClient.deleteByQuery(deleteByQueryRequest,RequestOptions.DEFAULT);
    }




    /**
     * 基于id修改
     * 基于查询修改
     *
     */
    public static void updateByID() throws IOException {
        String indexName = "movie_2022";
        String docId = "1004";
        UpdateRequest updateRequest = new UpdateRequest(indexName,docId);
        updateRequest.doc("movieName","八百");
        esClient.update(updateRequest,RequestOptions.DEFAULT);
    }
    public static void updateByQUery() throws IOException {
        String indexName = "movie_index";

        UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(indexName);
        //term
        //TermQueryBuilder termQueryBuilder = new TermQueryBuilder();
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name.keyword", "incident res sea");
        updateByQueryRequest.setQuery(termQueryBuilder);

        //script
        Map<String, Object> params = new HashMap<>();
        params.put("newName","shangguiug");
        Script script = new Script(ScriptType.INLINE,
                Script.DEFAULT_SCRIPT_LANG,
                "ctx._source['actorList'][0]['name']=params.newName",
                params
                );
        updateByQueryRequest.setScript(script);
        esClient.updateByQuery(updateByQueryRequest,RequestOptions.DEFAULT);
    }

    /**
     * 写数据 幂等写和非幂等写
     */
    //幂等写
    public static void put() throws IOException {
        Movie movie = new Movie("1001", "红海行动");
        String index = "movie_2022";
        IndexRequest indexRequest = new IndexRequest(index);
        indexRequest.id("1001");
        indexRequest.source(JSON.toJSONString(movie), XContentType.JSON);
        esClient.index(indexRequest, RequestOptions.DEFAULT);

    }
    //非幂等写
    public static void post() throws IOException {
        Movie movie = new Movie("1002", "湄公河行动");
        String index = "movie_2022";
        IndexRequest indexRequest = new IndexRequest(index);
        //indexRequest.id("1001");
        indexRequest.source(JSON.toJSONString(movie), XContentType.JSON);
        esClient.index(indexRequest, RequestOptions.DEFAULT);

    }

    /**
     * 批量写入
     */
    public static void bulk() throws IOException {
        Movie movie1 = new Movie("1003", "长津湖");
        Movie movie2 = new Movie("1004", "水门桥");
        List<Movie> movies = new ArrayList<>();
        movies.add(movie1);
        movies.add(movie2);
        String indexName = "movie_2022";


        BulkRequest bulkRequest = new BulkRequest(indexName);
        for (Movie movie : movies) {
            IndexRequest indexRequest = new IndexRequest();
            indexRequest.id(movie.getId());
            indexRequest.source(JSON.toJSONString(movie),XContentType.JSON);
            bulkRequest.add(indexRequest);
        }
        esClient.bulk(bulkRequest,RequestOptions.DEFAULT);
    }



    private  static RestHighLevelClient esClient = createClient();
    public static RestHighLevelClient createClient(){
        //HttpHost httpHost = new HttpHost("hadoop102", 9200);
        HttpHost httpHost [] = {
                new HttpHost("hadoop102", 9200),
                new HttpHost("hadoop103", 9200),
                new HttpHost("hadoop104", 9200),
        };
        RestClientBuilder restClientBuilder = RestClient.builder(httpHost);
        RestHighLevelClient restHighLevelClient = new RestHighLevelClient(restClientBuilder);

        return restHighLevelClient;
    }

    public static void close() throws IOException {
        if (esClient != null){
            esClient.close();
        }
    }
}

class Movie {
    private String id;
    private String name;

    public Movie(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
